import { Portal } from '@chakra-ui/react';
import { Fragment, ReactNode, createContext, useState, useCallback } from 'react';

type ItemType = {
  key: string;
  node: ReactNode;
};

export type PortalContextType = {
  addToPortal: (key: string, node: ReactNode) => void;
  removeFromPortal: (key: string) => void;
};

export const PortalContext = createContext<PortalContextType>({
  addToPortal: () => {},
  removeFromPortal: () => {}
});

const PortalProvider = ({ children }: { children: ReactNode }) => {
  const [list, setList] = useState<ItemType[]>([]);

  const addToPortal = useCallback((key: string, node: ReactNode) => {
    setList((state) => {
      const index = state.findIndex((item) => item.key === key);
      return index < 0
        ? [...state, { key, node }]
        : [...state.slice(0, index), { key, node }, ...state.slice(index + 1)];
    });
  }, []);

  const removeFromPortal = useCallback((key: string) => {
    setList((state) => state.filter((item) => item.key !== key));
  }, []);

  return (
    <PortalContext.Provider
      value={{
        addToPortal,
        removeFromPortal
      }}
    >
      {children}
      <Portal>
        {list.map((item) => (
          <Fragment key={item.key}>{item.node}</Fragment>
        ))}
      </Portal>
    </PortalContext.Provider>
  );
};

export default PortalProvider;
